home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS02.ADF / IFF / iffcheck.c < prev    next >
Text File  |  1989-05-30  |  6KB  |  208 lines

  1. /*---------------------------------------------------------------------*
  2.  * IFFCheck.C  Print out the structure of an IFF-85 file,      11/15/85
  3.  * checking for structural errors.
  4.  *
  5.  * DO NOT USE THIS AS A SKELETAL PROGRAM FOR AN IFF READER!
  6.  * See ShowILBM.C for a skeletal example.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10. #include "iff/iff.h"
  11.  
  12.  
  13. /* ---------- IFFCheck -------------------------------------------------*/
  14. /* [TBD] More extensive checking could be done on the IDs encountered in the
  15.  * file. Check that the reserved IDs "FOR1".."FOR9", "LIS1".."LIS9", and
  16.  * "CAT1".."CAT9" aren't used. Check that reserved IDs aren't used as Form
  17.  * types. Check that all IDs are made of 4 printable characters (trailing
  18.  * spaces ok). */
  19.  
  20. typedef struct {
  21.     ClientFrame clientFrame;
  22.     int levels;        /* # groups currently nested within.*/
  23.     } Frame;
  24.  
  25. char MsgOkay[] = { "----- (IFF_OKAY) A good IFF file." };
  26. char MsgEndMark[] = {"----- (END_MARK) How did you get this message??" };
  27. char MsgDone[] = { "----- (IFF_DONE) How did you get this message??" };
  28. char MsgDos[] = { "----- (DOS_ERROR) The DOS gave back an error." };
  29. char MsgNot[] = { "----- (NOT_IFF) not an IFF file." };
  30. char MsgNoFile[] = { "----- (NO_FILE) no such file found." };
  31. char MsgClientError[] = {"----- (CLIENT_ERROR) IFF Checker bug."};
  32. char MsgForm[] = { "----- (BAD_FORM) How did you get this message??" };
  33. char MsgShort[] = { "----- (SHORT_CHUNK) How did you get this message??" };
  34. char MsgBad[] = { "----- (BAD_IFF) a mangled IFF file." };
  35.  
  36. /* MUST GET THESE IN RIGHT ORDER!!*/
  37. char *IFFPMessages[-LAST_ERROR+1] = {
  38.     /*IFF_OKAY*/  MsgOkay,
  39.     /*END_MARK*/  MsgEndMark,
  40.     /*IFF_DONE*/  MsgDone,
  41.     /*DOS_ERROR*/ MsgDos,
  42.     /*NOT_IFF*/   MsgNot,
  43.     /*NO_FILE*/   MsgNoFile,
  44.     /*CLIENT_ERROR*/ MsgClientError,
  45.     /*BAD_FORM*/  MsgForm,
  46.     /*SHORT_CHUNK*/  MsgShort,
  47.     /*BAD_IFF*/   MsgBad
  48.     };
  49.  
  50. /* FORWARD REFERENCES */
  51. extern IFFP GetList(GroupContext *);
  52. extern IFFP GetForm(GroupContext *);
  53. extern IFFP GetProp(GroupContext *);
  54. extern IFFP GetCat (GroupContext *);
  55.  
  56. void IFFCheck(name)  char *name; {
  57.     IFFP iffp;
  58.     BPTR file = Open(name, MODE_OLDFILE);
  59.     Frame frame;
  60.  
  61.     frame.levels = 0;
  62.     frame.clientFrame.getList = &GetList;
  63.     frame.clientFrame.getForm = &GetForm;
  64.     frame.clientFrame.getProp = &GetProp;
  65.     frame.clientFrame.getCat  = &GetCat ;
  66.  
  67.     printf("----- Checking file '%s' -----\n", name);
  68.     if (file == 0)
  69.     iffp = NO_FILE;
  70.     else
  71.     iffp = ReadIFF(file, (ClientFrame *)&frame);
  72.  
  73.     Close(file);
  74.     printf("%s\n", IFFPMessages[-iffp]);
  75.     }
  76.  
  77. main(argc, argv)   int argc;  char **argv; {
  78.     if (argc != 1+1) {
  79.     printf("Usage: 'iffcheck filename'\n");
  80.     exit(0);
  81.     }
  82.     IFFCheck(argv[1]);
  83.     }
  84.  
  85. /* ---------- Put... ---------------------------------------------------*/
  86.  
  87. PutLevels(count)   int count; {
  88.     for ( ;  count > 0;  --count) {
  89.     printf(".");
  90.     }
  91.     }
  92.  
  93. PutID(id)  ID id; {
  94.     printf("%c%c%c%c", (id>>24)&0x7f, (id>>16)&0x7f, (id>>8)&0x7f, id&0x7f);
  95.     }
  96.  
  97. PutN(n)   int n; {
  98.     printf(" %d ", n);
  99.     }
  100.  
  101. /* Put something like "...BMHD 14" or "...LIST 14 PLBM". */
  102. PutHdr(context)  GroupContext *context; {
  103.     PutLevels( ((Frame *)context->clientFrame)->levels );
  104.     PutID(context->ckHdr.ckID);
  105.     PutN(context->ckHdr.ckSize);
  106.  
  107.     if (context->subtype != NULL_CHUNK)
  108.     PutID(context->subtype);
  109.  
  110.     printf("\n");
  111.     }
  112.  
  113. /* ---------- AtLeaf ---------------------------------------------------*/
  114.  
  115. /* At Leaf chunk.  That is, a chunk which does NOT contain other chunks.
  116.  * Print "ID size".*/
  117. IFFP AtLeaf(context)  GroupContext *context; {
  118.  
  119.     PutHdr(context);
  120.     /* A typical reader would read the chunk's contents, using the "Frame"
  121.      * for local data, esp. shared property settings (PROP).*/
  122.     /* IFFReadBytes(context, ...buffer, context->ckHdr->ckSize); */
  123.     return(IFF_OKAY);
  124.     }
  125.  
  126. /* ---------- GetList --------------------------------------------------*/
  127. /* Handle a LIST chunk.  Print "LIST size subTypeID".
  128.  * Then dive into it.*/
  129. IFFP GetList(parent)  GroupContext *parent; {
  130.     Frame newFrame;
  131.  
  132.     newFrame = *(Frame *)parent->clientFrame;  /* copy parent's frame*/
  133.     newFrame.levels++;
  134.  
  135.     PutHdr(parent);
  136.  
  137.     return( ReadIList(parent, (ClientFrame *)&newFrame) );
  138.     }
  139.  
  140. /* ---------- GetForm --------------------------------------------------*/
  141. /* Handle a FORM chunk.  Print "FORM size subTypeID".
  142.  * Then dive into it.*/
  143. IFFP GetForm(parent)   GroupContext *parent; {
  144.     /*CompilerBug register*/ IFFP iffp;
  145.     GroupContext new;
  146.     Frame newFrame;
  147.  
  148.     newFrame = *(Frame *)parent->clientFrame;  /* copy parent's frame*/
  149.     newFrame.levels++;
  150.  
  151.     PutHdr(parent);
  152.  
  153.     iffp = OpenRGroup(parent, &new);
  154.     CheckIFFP();
  155.     new.clientFrame = (ClientFrame *)&newFrame;
  156.  
  157.     /* FORM reader for Checker. */
  158.     /* LIST, FORM, PROP, CAT already handled by GetF1ChunkHdr. */
  159.     do {if ( (iffp = GetF1ChunkHdr(&new)) > 0 )
  160.         iffp = AtLeaf(&new);
  161.     } while (iffp >= IFF_OKAY);
  162.  
  163.     CloseRGroup(&new);
  164.     return(iffp == END_MARK ? IFF_OKAY : iffp);
  165.     }
  166.  
  167. /* ---------- GetProp --------------------------------------------------*/
  168. /* Handle a PROP chunk.  Print "PROP size subTypeID".
  169.  * Then dive into it.*/
  170. IFFP GetProp(listContext)  GroupContext *listContext; {
  171.     /*CompilerBug register*/ IFFP iffp;
  172.     GroupContext new;
  173.  
  174.     PutHdr(listContext);
  175.  
  176.     iffp = OpenRGroup(listContext, &new);
  177.     CheckIFFP();
  178.  
  179.     /* PROP reader for Checker. */
  180.     ((Frame *)listContext->clientFrame)->levels++;
  181.  
  182.     do {if ( (iffp = GetPChunkHdr(&new)) > 0 )
  183.         iffp = AtLeaf(&new);
  184.     } while (iffp >= IFF_OKAY);
  185.  
  186.     ((Frame *)listContext->clientFrame)->levels--;
  187.  
  188.     CloseRGroup(&new);
  189.     return(iffp == END_MARK ? IFF_OKAY : iffp);
  190.     }
  191.  
  192. /* ---------- GetCat ---------------------------------------------------*/
  193. /* Handle a CAT chunk.  Print "CAT size subTypeID".
  194.  * Then dive into it.*/
  195. IFFP GetCat(parent)  GroupContext *parent;  {
  196.     IFFP iffp;
  197.  
  198.     ((Frame *)parent->clientFrame)->levels++;
  199.  
  200.     PutHdr(parent);
  201.  
  202.     iffp = ReadICat(parent);
  203.  
  204.     ((Frame *)parent->clientFrame)->levels--;
  205.     return(iffp);
  206.     }
  207.  
  208.